using System;
using System.Collections.Generic;
using System.Text;
using ACS.Compiler.Tables.Modes;
using ACS.Compiler.Tree.Interfaces;

namespace ACS.Compiler.Tree.Impl
{
    public abstract class Operator : Expression
    {
        private IExpression _left;
        private IExpression _right;

        public override void MatchSelect(Select select)
        {
            MatchExpression(select);
        }

        public override void MatchExpression(IExpression expression)
        {
            if (_left == null)
            {
                _left = expression;
            } else
            {
                _right = expression;
            }  
        }

        public override void MatchCall(Call call)
        {
            MatchExpression(call);
        }

        public override void MatchIdent(Ident ident)
        {
            MatchExpression(ident);
        }

        public enum Operators {Plus, Star, Arrow, Eqq}

        public override Expressions ExpressionType
        {
            get
            {
                switch (OperatorType)
                {
                    case Operators.Plus:
                        return Expressions.Plus;
                    case Operators.Star:
                        return Expressions.Star;
                    case Operators.Arrow:
                        return Expressions.Arrow;
                    case Operators.Eqq:
                        return Expressions.Eqq;
                    default:
                        break;
                }
                throw new Exception("Wron operator type.");
            }
        }

        public override string ToDeclareString()
        {
            string s1 = _left.ToDeclareString();
            string s2 = _right.ToDeclareString();
            return String.Format("({0}) {1} ({2})", s1, OperatorToString(), s2);
        }

        public abstract string OperatorToString();
        

        public abstract Operators OperatorType
        {
            get;
        }


        public IExpression Left
        {
            get { return _left; }
        }

        public IExpression Right
        {
            get { return _right; }
        }
    }
}
